<!-- 每个回话对应的聊天内容 -->
<script setup lang="ts">
import type { BubbleListInstance } from 'vue-element-plus-x/types/BubbleList';
import type { FilesCardProps } from 'vue-element-plus-x/types/FilesCard';
import type { MessageItem } from './chat';
import {
  ArrowLeftBold,
  ArrowRightBold,
  Document,
  DocumentCopy,
  Download,
  Edit,
  Refresh,
  Share,
  VideoPlay,
  View,
} from '@element-plus/icons-vue';
import { ElMessage, ElMessageBox } from 'element-plus';
// 使用 radash 的防抖函数
import { debounce } from 'radash';
import { onMounted, onUnmounted } from 'vue';
// no local BubbleProps/ThinkingStatus usage after refactor
import { useRoute, useRouter } from 'vue-router';
import { getWorkflowMessages } from '@/api/chat/workflow';
import agentAvatar from '@/assets/images/logo.png';
import userAvatar from '@/assets/images/user.png';
import AgentSelect from '@/components/AgentSelect/index.vue';
import ChatWelcome from '@/components/ChatWelcome/index.vue';
import DeepThinkingToggle from '@/components/DeepThinkingToggle/index.vue';
import FilesSelect from '@/components/FilesSelect/index.vue';
import MarkdownEditor from '@/components/MarkdownEditor/index.vue';
import PPTPreview from '@/components/PPTPreview/index.vue';
import { chatService } from '@/services/chatService';
import PPTService from '@/services/pptService';
import { useAgentStore } from '@/stores/modules/agent';
import { useAppStore } from '@/stores/modules/app';
import { useChatStore } from '@/stores/modules/chat';
import { useFilesStore } from '@/stores/modules/files';
import { useSessionStore } from '@/stores/modules/session';
import { useUserStore } from '@/stores/modules/user';
import { copyHandle, copyMarkdownAsText } from '@/utils/copy';
import { convertMarkdownToRTF, convertMarkdownToWord } from '@/utils/docxUtils';

import { buildChatHandlers } from './chat';
// 使用 FilesCard 内置文件类型图标

// types moved to chat.ts and imported above

const route = useRoute();
const router = useRouter();
const chatStore = useChatStore();
const filesStore = useFilesStore();
const sessionStore = useSessionStore();
const userStore = useUserStore();
const appStore = useAppStore();
const agentStore = useAgentStore();

// 用户头像
const avatar = computed(() => {
  const userInfo = userStore.userInfo;
  return userInfo?.avatar || userAvatar;
});

// 确保聊天服务有正确的用户信息
watchEffect(() => {
  const username = userStore.userInfo?.username || 'guest';
  if (username) {
    chatService.setUser(username);
  }
});

const inputValue = ref('');
// 为 senderRef 提供最小可用类型，避免直接依赖未导入的 Sender 符号
interface MinimalSenderExpose {
  openHeader?: () => void;
  closeHeader?: () => void;
}
const senderRef = ref<MinimalSenderExpose | null>(null);
const bubbleItems = ref<MessageItem[]>([]);
const bubbleListRef = ref<BubbleListInstance | null>(null);

const isLoading = ref(false);

// 结果展示区域宽度控制
const resultWidth = ref(80); // 默认80%宽度

// 是否显示欢迎页面
const showWelcome = ref(true);

// 当前选中的智能体
const currentAgent = computed(() => agentStore.currentAgent?.name || '通用智能体');

// 创建防抖的会话列表刷新函数
const debouncedRefreshSessionList = debounce({ delay: 300 }, async () => {
  console.log('执行智能体切换后的会话列表刷新');
  await sessionStore.requestSessionList(1, true);
});

// 监听智能体切换，刷新会话列表
watch(() => agentStore.currentAgent?.keyStr, async (newKeyStr, oldKeyStr) => {
  if (newKeyStr && oldKeyStr && newKeyStr !== oldKeyStr) {
    console.log('智能体切换，准备刷新会话列表');
    // 使用防抖函数，避免快速切换时的重复请求
    debouncedRefreshSessionList();
  }
}, { immediate: false });

// 组合业务逻辑 - 从 chat.ts 抽离
const {
  initResultWidth,
  // splitThink,
  loadConversationById,
  startSSE,
  cancelSSE,
  addMessage,
  handleWorkflowChunk,
  handleDeleteCard,
  scrollToBottom,
} = buildChatHandlers({
  chatService,
  filesStore,
  userStore,
  appStore,
  chatStore,
  sessionStore,
  getWorkflowMessages,
  agentAvatar,
  getUserAvatar: () => avatar.value as string,
  bubbleItems,
  bubbleListRef,
  inputValue,
  isLoading,
  resultWidth,
  currentAgent,
  route,
  router,
});

// 初始化结果宽度
initResultWidth();

watch(
  () => route.params?.id,
  async (_id_) => {
    if (_id_) {
      if (_id_ !== 'not_login') {
        // 判断的当前会话id是否有聊天记录，有缓存则直接赋值展示
        const existingChats = chatStore.chatMap[`${_id_}`];
        if (existingChats && Array.isArray(existingChats) && existingChats.length > 0) {
          bubbleItems.value = existingChats as MessageItem[];
          showWelcome.value = false; // 有聊天记录时隐藏欢迎页面
          // 设置会话ID到chatService
          chatService.setConversationId(String(_id_));
          // 滚动到底部
          nextTick(scrollToBottom);
          return;
        }

        await loadConversationById(String(_id_));

        // 如果加载到了聊天记录，隐藏欢迎页面
        if (bubbleItems.value.length > 0) {
          showWelcome.value = false;
        }

        // 滚动到底部
        nextTick(scrollToBottom);
      }

      // 如果本地有发送内容 ，则直接发送
      const v = localStorage.getItem('chatContent');
      if (v) {
        // 发送消息
        console.log('发送消息 v', v);
        showWelcome.value = false; // 开始对话时隐藏欢迎页面
        nextTick(() => {
          startSSE(v);
        });

        localStorage.removeItem('chatContent');
      }
    }
    else {
      // 新建会话：清空聊天记录和会话ID，显示欢迎页面
      bubbleItems.value = [];
      showWelcome.value = true;
      chatService.createNewConversation();
    }
  },
  { immediate: true, deep: true },
);

// 以上方法均来自 buildChatHandlers

watch(
  () => filesStore.filesList?.length || 0,
  (val) => {
    if (val > 0) {
      nextTick(() => {
        senderRef.value?.openHeader();
      });
    }
    else {
      nextTick(() => {
        senderRef.value?.closeHeader();
      });
    }
  },
);

// 重新生成状态管理
const regeneratingStates = ref<Record<number, boolean>>({});

// 按钮点击处理函数
async function handleRegenerate(item: MessageItem) {
  console.log('重新生成:', item);

  if (item.role !== 'system') {
    ElMessage.warning('只能重新生成AI回复');
    return;
  }

  // 防止重复点击
  if (regeneratingStates.value[item.key] || isLoading.value) {
    return;
  }

  try {
    // 找到这条AI回复对应的用户问题
    const currentIndex = bubbleItems.value.findIndex(msg => msg.key === item.key);
    if (currentIndex === -1) {
      ElMessage.error('无法找到对应的消息');
      return;
    }

    // 向前查找最近的用户消息
    let userMessageIndex = -1;
    for (let i = currentIndex - 1; i >= 0; i--) {
      if (bubbleItems.value[i].role === 'user') {
        userMessageIndex = i;
        break;
      }
    }

    if (userMessageIndex === -1) {
      ElMessage.error('无法找到对应的用户问题');
      return;
    }

    const userMessage = bubbleItems.value[userMessageIndex];

    // 检查是否会删除后续消息
    const hasSubsequentMessages = currentIndex < bubbleItems.value.length - 1;
    if (hasSubsequentMessages) {
      // 可以添加确认对话框
      const confirmResult = await ElMessageBox.confirm(
        '重新生成将删除此回复之后的所有消息，是否继续？',
        '确认重新生成',
        {
          confirmButtonText: '确定',
          cancelButtonText: '取消',
          type: 'warning',
        },
      ).catch(() => false);

      if (!confirmResult) {
        return;
      }
    }

    // 设置重新生成状态
    regeneratingStates.value[item.key] = true;

    // 删除从当前AI回复开始的所有后续消息
    const messagesToKeep = bubbleItems.value.slice(0, currentIndex);
    bubbleItems.value = messagesToKeep;

    // 重新发送用户消息，触发AI回复
    const userContent = userMessage.content || '';
    const userAttachments = userMessage.attachments || [];

    // 添加新的AI回复占位符
    addMessage('', false);

    // 滚动到底部
    nextTick(scrollToBottom);

    // 设置加载状态
    isLoading.value = true;

    // 准备文件数据（如果有附件的话）
    const files = userAttachments.length > 0
      ? await chatService.uploadFilesIfNeeded(
          userAttachments.map(att => ({
            name: att.name,
            url: att.url,
            size: att.size,
            type: att.type,
          })),
          userStore.userInfo?.username || 'guest',
        )
      : [];

    // 使用原消息的智能体，如果没有则使用当前选中的智能体
    const agentToUse = item.agent || currentAgent?.value;

    // 发送消息流
    await chatService.sendMessageStream(
      userContent,
      {},
      files,
      (chunk: any) => {
        handleWorkflowChunk(chunk);
      },
      (error: any) => {
        console.error('重新生成时流式消息错误:', error);
        ElMessage.error('重新生成失败，请稍后重试');
      },
      agentToUse,
    );

    ElMessage.success('正在重新生成回复...');
  }
  catch (error) {
    console.error('重新生成失败:', error);
    ElMessage.error('重新生成失败，请稍后重试');

    // 如果发生错误，恢复原来的消息
    if (item.content) {
      // 移除刚添加的空消息
      if (bubbleItems.value.length > 0 && !bubbleItems.value[bubbleItems.value.length - 1].content) {
        bubbleItems.value.pop();
      }
      // 重新添加原消息
      bubbleItems.value.push(item);
    }
  }
  finally {
    isLoading.value = false;
    regeneratingStates.value[item.key] = false;

    // 更新聊天缓存
    const route = useRoute();
    if (route.params?.id && route.params.id !== 'not_login') {
      chatStore.updateChatMap(String(route.params.id), bubbleItems.value);
    }
  }
}

// 复制状态管理
const copyingStates = ref<Record<number, boolean>>({});

// 编辑器状态管理
const showMarkdownEditor = ref(false);
const editingContent = ref('');
const editingItem = ref<MessageItem | null>(null);

// PPT 相关状态管理
const showPPTPreview = ref(false);
const pptPreviewUrl = ref('');
const pptDownloadUrl = ref('');
const pptGenerating = ref<Record<number, boolean>>({});

// Word 文档生成状态
const wordGenerating = ref<Record<number, boolean>>({});

async function handleCopy(item: MessageItem) {
  if (!item.content) {
    ElMessage.warning('没有可复制的内容');
    return;
  }

  // 设置复制状态
  copyingStates.value[item.key] = true;

  try {
    // 如果是系统消息（AI回复），通常是Markdown格式，提供选择
    if (item.role === 'system') {
      // 可以根据需要选择复制原始Markdown还是纯文本
      await copyMarkdownAsText(item.content);
    }
    else {
      // 用户消息直接复制
      await copyHandle(item.content);
    }
  }
  finally {
    // 清除复制状态
    setTimeout(() => {
      copyingStates.value[item.key] = false;
    }, 500);
  }
}

// 文档处理智能体按钮处理
async function handleCopyDocument(item: MessageItem) {
  console.log('复制文档:', item);
  copyingStates.value[item.key] = true;

  try {
    await handleCopy(item);
  }
  finally {
    setTimeout(() => {
      copyingStates.value[item.key] = false;
    }, 500);
  }
}

function handleShareDocument(item: MessageItem) {
  console.log('分享文档:', item);
  ElMessage.info('分享文档功能');
}

// 编辑 Markdown 内容
function handleEditMarkdown(item: MessageItem) {
  if (!item.content) {
    ElMessage.warning('没有可编辑的内容');
    return;
  }

  editingItem.value = item;
  editingContent.value = item.content;
  showMarkdownEditor.value = true;
}

// 保存编辑后的内容
function handleSaveMarkdown(content: string) {
  if (editingItem.value) {
    editingItem.value.content = content;

    // 更新聊天缓存
    const route = useRoute();
    if (route.params?.id && route.params.id !== 'not_login') {
      chatStore.updateChatMap(String(route.params.id), bubbleItems.value);
    }

    ElMessage.success('内容已更新');
  }
  editingItem.value = null;
}

// 生成 Word 文档（方案1：markdown-it + html-docx）
async function handleGenerateWord(item: MessageItem) {
  if (!item.content) {
    ElMessage.warning('没有可导出的内容');
    return;
  }

  wordGenerating.value[item.key] = true;

  try {
    const filename = `chat-content-${Date.now()}`;
    await convertMarkdownToWord(item.content, filename);
    ElMessage.success('Word文档生成成功');
  }
  catch (error) {
    console.error('生成Word文档失败:', error);
    ElMessage.error('生成Word文档失败，请稍后重试');
  }
  finally {
    wordGenerating.value[item.key] = false;
  }
}

// 生成 RTF 文档（方案2：更兼容的格式）
function _handleGenerateRTF(item: MessageItem) {
  if (!item.content) {
    ElMessage.warning('没有可导出的内容');
    return;
  }

  wordGenerating.value[item.key] = true;

  try {
    const filename = `chat-content-${Date.now()}`;
    convertMarkdownToRTF(item.content, filename);
    ElMessage.success('RTF文档生成成功');
  }
  catch (error) {
    console.error('生成RTF文档失败:', error);
    ElMessage.error('生成RTF文档失败，请稍后重试');
  }
  finally {
    wordGenerating.value[item.key] = false;
  }
}

// 生成 PPT（仅限"生成MarkDown大纲"智能体）
async function handleGeneratePPT(item: MessageItem) {
  if (!item.content) {
    ElMessage.warning('没有可生成PPT的内容');
    return;
  }

  // 验证内容是否适合生成PPT
  const validation = PPTService.validateMarkdownForPPT(item.content);
  if (!validation.valid) {
    ElMessage.warning(validation.message);
    return;
  }

  pptGenerating.value[item.key] = true;

  try {
    const result = await PPTService.generatePPT(item.content);

    if (result.success && result.downloadUrl) {
      pptDownloadUrl.value = result.downloadUrl;
      ElMessage.success(result.message || '生成PPT成功！');
    }
    else {
      ElMessage.error(result.message || '生成PPT失败');
    }
  }
  catch (error) {
    console.error('生成PPT失败:', error);
    ElMessage.error('生成PPT失败，请稍后重试');
  }
  finally {
    pptGenerating.value[item.key] = false;
  }
}

// 预览 PPT
function handlePreviewPPT() {
  if (!pptDownloadUrl.value) {
    ElMessage.warning('没有可预览的PPT文件');
    return;
  }

  pptPreviewUrl.value = PPTService.getPPTPreviewUrl(pptDownloadUrl.value);
  showPPTPreview.value = true;
}

// 下载 PPT
function handleDownloadPPT() {
  if (!pptDownloadUrl.value) {
    ElMessage.warning('没有可下载的PPT文件');
    return;
  }

  PPTService.downloadPPT(pptDownloadUrl.value);
}

// 处理Markdown中代码块的复制
async function handleCopyCodeBlock(code: string, language?: string) {
  console.log('复制代码块:', { code, language });
  await copyHandle(code);
}

// 复制选项处理
const handleCopyOptions = {
  // 复制原始内容（包含Markdown格式）
  copyRaw: async (item: MessageItem) => {
    if (item.content) {
      await copyHandle(item.content);
    }
  },

  // 复制纯文本（去除Markdown格式）
  copyPlainText: async (item: MessageItem) => {
    if (item.content) {
      await copyMarkdownAsText(item.content);
    }
  },

  // 复制所有代码块
  copyAllCode: async (item: MessageItem) => {
    if (!item.content)
      return;

    const codeBlocks = item.content.match(/```[\s\S]*?```/g);
    if (codeBlocks && codeBlocks.length > 0) {
      const allCode = codeBlocks
        .map(block => block.replace(/```\w*\n?/g, '').replace(/```$/g, ''))
        .join('\n\n');
      await copyHandle(allCode);
    }
    else {
      ElMessage.info('该消息中没有代码块');
    }
  },
};

// 键盘快捷键处理
function handleKeydown(event: KeyboardEvent) {
  // 检查是否在输入框中，如果是则不处理快捷键
  const target = event.target as HTMLElement;
  const isInInput = target.tagName === 'INPUT' || target.tagName === 'TEXTAREA' || target.contentEditable === 'true';

  // Ctrl+C 或 Cmd+C 复制最后一条AI回复
  if ((event.ctrlKey || event.metaKey) && event.key === 'c' && !event.shiftKey && !isInInput) {
    // 查找最后一条AI回复
    const lastAIMessage = [...bubbleItems.value].reverse().find(item => item.role === 'system');
    if (lastAIMessage) {
      event.preventDefault();
      handleCopy(lastAIMessage);
    }
  }

  // Ctrl+R 或 Cmd+R 重新生成最后一条AI回复
  if ((event.ctrlKey || event.metaKey) && event.key === 'r' && !isInInput) {
    event.preventDefault();

    // 查找最后一条AI回复
    const lastAIMessage = [...bubbleItems.value].reverse().find(item => item.role === 'system');
    if (lastAIMessage && !isLoading.value) {
      handleRegenerate(lastAIMessage);
    }
    else if (isLoading.value) {
      ElMessage.info('请等待当前消息完成后再重新生成');
    }
    else {
      ElMessage.info('没有可重新生成的AI回复');
    }
  }
}

// 组件挂载时添加键盘监听
onMounted(() => {
  document.addEventListener('keydown', handleKeydown);
});

// 组件卸载时移除键盘监听和清理防抖函数
onUnmounted(() => {
  document.removeEventListener('keydown', handleKeydown);

  // 取消防抖函数的待执行任务
  debouncedRefreshSessionList.cancel();
});

// 右键菜单相关
const contextMenuVisible = ref(false);
const contextMenuPosition = ref({ x: 0, y: 0 });
const contextMenuItem = ref<MessageItem | null>(null);

function showContextMenu(event: MouseEvent, item: MessageItem) {
  contextMenuItem.value = item;
  contextMenuPosition.value = { x: event.clientX, y: event.clientY };
  contextMenuVisible.value = true;

  // 点击其他地方关闭菜单
  const closeMenu = () => {
    contextMenuVisible.value = false;
    document.removeEventListener('click', closeMenu);
  };

  setTimeout(() => {
    document.addEventListener('click', closeMenu);
  }, 0);
}

async function handleContextMenuAction(action: string) {
  if (!contextMenuItem.value)
    return;

  contextMenuVisible.value = false;

  switch (action) {
    case 'copy':
      await handleCopy(contextMenuItem.value);
      break;
    case 'copyRaw':
      await handleCopyOptions.copyRaw(contextMenuItem.value);
      break;
    case 'copyPlainText':
      await handleCopyOptions.copyPlainText(contextMenuItem.value);
      break;
    case 'copyAllCode':
      await handleCopyOptions.copyAllCode(contextMenuItem.value);
      break;
  }
}

// 根据大纲生成报告内容
async function handleGenerateReportContent(item: MessageItem) {
  if (!item.content) {
    ElMessage.warning('没有可用的大纲内容');
    return;
  }

  try {
    // 查找"所级报告内容生成"智能体
    const reportContentAgent = appStore.agents.find(agent => agent.name === '所级报告内容生成');

    if (!reportContentAgent) {
      ElMessage.error('未找到"所级报告内容生成"智能体');
      return;
    }

    // 切换到报告内容生成智能体
    agentStore.setCurrentAgent(reportContentAgent);

    // 等待智能体设置完成
    await nextTick();

    // 构建提示词，包含大纲内容
    const prompt = `请根据以下大纲生成详细的报告内容：\n\n${item.content}`;

    // 隐藏欢迎页面
    showWelcome.value = false;

    // 发送消息
    startSSE(prompt, reportContentAgent.name);

    ElMessage.success('正在根据大纲生成报告内容...');
  }
  catch (error) {
    console.error('生成报告内容失败:', error);
    ElMessage.error('生成报告内容失败，请稍后重试');
  }
}

// 处理快捷功能点击
async function handleQuickAction(action: { agent: string; prompt: string }) {
  // 隐藏欢迎页面
  showWelcome.value = false;

  // 从 app store 中根据名称找到对应的完整智能体信息
  const targetAgent = appStore.agents.find(agent => agent.name === action.agent);

  if (targetAgent) {
    // 设置完整的智能体信息（包括 keyStr）
    agentStore.setCurrentAgent(targetAgent);
  }
  else {
    // 如果没找到，至少更新名称
    agentStore.setCurrentAgent({
      ...agentStore.currentAgent,
      name: action.agent,
    });
  }

  // 发送消息
  if (action.prompt) {
    // 等待智能体设置完成
    await nextTick();

    // 直接传递智能体参数，确保使用正确的智能体
    startSSE(action.prompt, action.agent);
  }
}

// 包装startSSE函数，在开始对话时隐藏欢迎页面
function handleStartSSE(content: string) {
  showWelcome.value = false;
  startSSE(content);
}
</script>

<template>
  <div class="chat-with-id-container" :style="{ maxWidth: `${resultWidth}%` }">
    <div class="chat-warp">
      <!-- 欢迎页面 -->
      <div v-if="showWelcome" class="welcome-container">
        <ChatWelcome @quick-action="handleQuickAction" />
      </div>

      <!-- 聊天内容 -->
      <BubbleList v-if="!showWelcome" ref="bubbleListRef" :list="bubbleItems" max-height="calc(100vh - 240px)">
        <template #header="{ item }">
          <!-- 使用库内置 Thinking 组件，支持状态样式、折叠与自动收起 -->
          <!-- :model-value="!item.thinlCollapse" -->
          <Thinking
            v-if="item.reasoning_content" :status="item.thinkingStatus || 'start'"
            :content="item.reasoning_content" button-width="210px" max-width="100%"
            @update:model-value="(val: boolean) => (item.thinlCollapse = !val)"
            @change="(p: any) => (item.thinlCollapse = !p.value)"
          >
            <template #label="{ status }">
              <span v-if="status === 'thinking'">正在深度思考...</span>
              <span v-else-if="status === 'end'">已深度思考<span v-if="item.thinkingTime">(用时{{ item.thinkingTime
              }}秒)</span></span>
              <span v-else>开始深度思考</span>
            </template>
          </Thinking>
        </template>

        <template #content="{ item }">
          <!-- chat 内容走 markdown -->
          <div v-if="item.content && item.role === 'system'" @contextmenu.prevent="(e) => showContextMenu(e, item)">
            <XMarkdown
              :markdown="item.content" class="markdown-body"
              :themes="{ light: 'github-light', dark: 'github-dark' }" default-theme-mode="light"
              @copy-code="handleCopyCodeBlock"
            />
          </div>
          <!-- 附件列表（仅当有附件时显示，不展示超链接，仅展示类型图标+名称+大小） -->
          <div v-if="item.attachments && item.attachments.length" class="attachments">
            <template v-for="att in item.attachments" :key="att.name">
              <FilesCard
                :name="att.name" :file-size="att.size" :url="att.url" icon-size="24px" description=" " :style="{
                  height: '32px',
                  gap: '2px',
                  background: '#fff',
                  padding: '4px 8px',
                  alignItems: 'center',
                  marginBottom: '6px',
                }"
              />
            </template>
          </div>
          <!-- user 内容 纯文本 -->
          <div
            v-if="item.content && item.role === 'user'" class="user-content"
            @contextmenu.prevent="(e) => showContextMenu(e, item)"
          >
            {{ item.content }}
          </div>
        </template>

        <!-- 自定义底部 - 仅对AI回答显示，且不在生成中时显示 -->
        <template #footer="{ item }">
          <div
            v-if="item.role === 'system' && !item.loading && !isLoading && item.content && item.thinkingStatus === 'end'"
            class="footer-wrapper"
          >
            <div class="footer-container">
              <el-button
                type="info" :icon="Refresh" size="small" circle title="重新生成 (Ctrl+R)"
                :loading="regeneratingStates[item.key]" :disabled="isLoading" @click="handleRegenerate(item)"
              />
              <el-button
                type="primary" :icon="Edit" size="small" circle title="编辑内容"
                @click="handleEditMarkdown(item)"
              />
              <el-button
                color="#626aef" :icon="DocumentCopy" size="small" circle title="复制内容 (Ctrl+C)"
                :loading="copyingStates[item.key]" @click="handleCopy(item)"
              />
              <el-button
                color="#67c23a" :icon="Document" size="small" circle title="生成Word文档"
                :loading="wordGenerating[item.key]" @click="handleGenerateWord(item)"
              />
              <!-- 通用智能体按钮 -->
              <template v-if="!item.agent || item.agent === '通用智能体'">
                <!-- <el-button type="success" :icon="Search" size="small" circle title="搜索相关" @click="handleSearch(item)" /> -->
              </template>

              <!-- 文档处理智能体按钮 -->
              <template v-else-if="item.agent === '文档处理智能体'">
                <el-button
                  type="primary" :icon="DocumentCopy" size="small" circle title="复制文档内容"
                  :loading="copyingStates[item.key]" @click="handleCopyDocument(item)"
                />
                <el-button
                  type="warning" :icon="Edit" size="small" circle title="编辑文档"
                  @click="handleEditMarkdown(item)"
                />
                <el-button
                  color="#626aef" :icon="Share" size="small" circle title="分享文档"
                  @click="handleShareDocument(item)"
                />
                <el-button
                  color="#67c23a" :icon="Document" size="small" circle title="生成Word文档"
                  :loading="wordGenerating[item.key]" @click="handleGenerateWord(item)"
                />
              </template>
              <!-- 生成MarkDown大纲智能体按钮 -->
              <template v-else-if="item.agent === '生成MarkDown大纲'">
                <el-button
                  color="#e6a23c" :icon="VideoPlay" size="small" circle title="生成PPT"
                  :loading="pptGenerating[item.key]" @click="handleGeneratePPT(item)"
                />
                <el-button
                  v-if="pptDownloadUrl" type="success" :icon="View" size="small" circle title="预览PPT"
                  @click="handlePreviewPPT"
                />
                <el-button
                  v-if="pptDownloadUrl" type="warning" :icon="Download" size="small" circle title="下载PPT"
                  @click="handleDownloadPPT"
                />
              </template>

              <!-- 所级报告大纲生成智能体按钮 -->
              <template v-else-if="item.agent === '所级报告大纲生成'">
                <el-button
                  color="#e6a23c" :icon="VideoPlay" size="small" circle title="生成PPT"
                  :loading="pptGenerating[item.key]" @click="handleGeneratePPT(item)"
                />
                <el-button
                  v-if="pptDownloadUrl" type="success" :icon="View" size="small" circle title="预览PPT"
                  @click="handlePreviewPPT"
                />
                <el-button
                  v-if="pptDownloadUrl" type="warning" :icon="Download" size="small" circle title="下载PPT"
                  @click="handleDownloadPPT"
                />
                <el-button
                  type="primary" :icon="Document" size="small" circle title="根据大纲生成报告内容"
                  @click="handleGenerateReportContent(item)"
                />
              </template>

              <!-- 其他智能体默认按钮 -->
              <template v-else />
            </div>
            <div class="footer-time">
              {{ new Date().toLocaleTimeString('zh-CN', { hour: '2-digit', minute: '2-digit' }) }}
            </div>
          </div>
        </template>
      </BubbleList>

      <Sender
        ref="senderRef" v-model="inputValue" class="chat-defaul-sender"
        :class="[{ 'sender-welcome': showWelcome }]" placeholder="我可以帮你处理各类文档的工作，例如内容提炼、AI润色、文档对比等，请把你的任务交给我吧~"
        :auto-size="{
          maxRows: 6,
          minRows: 2,
        }" variant="updown" clearable allow-speech :loading="isLoading" @submit="handleStartSSE" @cancel="cancelSSE"
      >
        <template #header>
          <div class="sender-header p-12px pt-6px pb-0px">
            <Attachments
              :items="filesStore.filesList as FilesCardProps[]" :hide-upload="true"
              @delete-card="handleDeleteCard"
            >
              <template #prev-button="{ show, onScrollLeft }">
                <div
                  v-if="show"
                  class="prev-next-btn left-8px flex-center w-22px h-22px rounded-8px border-1px border-solid border-[rgba(0,0,0,0.08)] c-[rgba(0,0,0,.4)] hover:bg-#f3f4f6 bg-#fff font-size-10px"
                  @click="onScrollLeft"
                >
                  <el-icon>
                    <ArrowLeftBold />
                  </el-icon>
                </div>
              </template>

              <template #next-button="{ show, onScrollRight }">
                <div
                  v-if="show"
                  class="prev-next-btn right-8px flex-center w-22px h-22px rounded-8px border-1px border-solid border-[rgba(0,0,0,0.08)] c-[rgba(0,0,0,.4)] hover:bg-#f3f4f6 bg-#fff font-size-10px"
                  @click="onScrollRight"
                >
                  <el-icon>
                    <ArrowRightBold />
                  </el-icon>
                </div>
              </template>
            </Attachments>
          </div>
        </template>
        <template #prefix>
          <div class="flex-1 flex items-center gap-8px flex-none w-fit flex-wrap">
            <FilesSelect />
            <!-- <ModelSelect /> -->
            <AgentSelect />
            <DeepThinkingToggle />
          </div>
        </template>
      </Sender>
    </div>
  </div>

  <!-- Markdown 编辑器 -->
  <MarkdownEditor
    v-model="showMarkdownEditor" :content="editingContent" @update:content="editingContent = $event"
    @save="handleSaveMarkdown"
  />

  <!-- PPT 预览 -->
  <PPTPreview v-model="showPPTPreview" :ppt-url="pptPreviewUrl" :download-url="pptDownloadUrl" />

  <!-- 右键菜单 -->
  <teleport to="body">
    <div
      v-if="contextMenuVisible" class="context-menu" :style="{
        position: 'fixed',
        left: `${contextMenuPosition.x}px`,
        top: `${contextMenuPosition.y}px`,
        zIndex: 9999,
      }"
    >
      <div class="context-menu-content">
        <div class="context-menu-item" @click="handleContextMenuAction('copy')">
          <el-icon>
            <DocumentCopy />
          </el-icon>
          <span>复制内容</span>
        </div>
        <div
          v-if="contextMenuItem?.role === 'system'" class="context-menu-item"
          @click="handleContextMenuAction('copyRaw')"
        >
          <el-icon>
            <DocumentCopy />
          </el-icon>
          <span>复制原始格式</span>
        </div>
        <div
          v-if="contextMenuItem?.role === 'system'" class="context-menu-item"
          @click="handleContextMenuAction('copyPlainText')"
        >
          <el-icon>
            <DocumentCopy />
          </el-icon>
          <span>复制纯文本</span>
        </div>
        <div
          v-if="contextMenuItem?.role === 'system' && contextMenuItem?.content?.includes('```')"
          class="context-menu-item" @click="handleContextMenuAction('copyAllCode')"
        >
          <el-icon>
            <DocumentCopy />
          </el-icon>
          <span>复制所有代码</span>
        </div>
      </div>
    </div>
  </teleport>
</template>

<style scoped lang="scss">
@use './chat';
</style>
